package com.snda.game.legend.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.snda.game.legend.base.BaseController;
import com.snda.game.legend.base.CommonParamter;
import com.snda.game.legend.base.ExcelUtils;
import com.snda.game.legend.common.Param;
import com.snda.game.legend.entiy.Acticle;
import com.snda.game.legend.entiy.Ad;
import com.snda.game.legend.entiy.Legend;
import com.snda.game.legend.enums.EnableState;
import com.snda.game.legend.enums.IndexState;
import com.snda.game.legend.enums.TopState;
import com.snda.game.legend.enums.TypeState;
import com.snda.game.legend.exception.Resource404Exception;
import com.snda.game.legend.service.ActicleService;
import com.snda.game.legend.service.AdService;
import com.snda.game.legend.service.LegendService;

@Controller
@RequestMapping("/admin")
public class AdminController extends BaseController {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger
            .getLogger(AdminController.class);

    @Resource
    private AdService adService;
    @Resource
    private LegendService legendService;
    @Resource
    private ActicleService acticleService;

    @RequestMapping("/index")
    public String index(Model model, HttpSession session) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        List<Legend> nextServers = legendService.queryNextServers();
        List<Legend> priviousServers = legendService.queryBeforeServers();
        Map<Integer, List<Ad>> ads = adService.getAllEnableAds();
        model.addAttribute("nextServers", nextServers);
        model.addAttribute("priviousServers", priviousServers);
        model.addAttribute("ads", ads);
        return "/admin/index";
    }

    @RequestMapping(value = { "/upload" }, method = RequestMethod.GET)
    public String upload(Model model, HttpSession session) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        return "/admin/upload";
    }

    @RequestMapping(value = { "/upload" }, method = RequestMethod.POST)
    public String upload(Model model, MultipartHttpServletRequest mhsRequest,
            HttpSession session) throws FileNotFoundException,
            SecurityException, IllegalArgumentException, NoSuchFieldException,
            InstantiationException, IllegalAccessException,
            NoSuchMethodException, InvocationTargetException {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        Map<String, MultipartFile> files = mhsRequest.getFileMap();
        MultipartFile file = files.get("file");
        // 产生随机的名字
        String tempName = String.valueOf(System.nanoTime())
                + file.getOriginalFilename().substring(
                        file.getOriginalFilename().lastIndexOf("."));
        String path = System.getProperty("web.root");
        if (path.indexOf("WEB-INF") > 0) {
            path = path.substring(0, path.indexOf("/WEB-INF/classes") + 16);
            // ‘/WEB-INF/classes’为16位
        }
        File dest = new File(path + CommonParamter.uploadPath
                + File.separatorChar + tempName);
        try {
            file.transferTo(dest);
        } catch (IllegalStateException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        ExcelUtils<Legend> excelUtils = new ExcelUtils<Legend>(Legend.class);
        List<Legend> list = excelUtils.readExcel(dest.getPath(),
                0 * ExcelUtils.MaxReadOrWriteLine);
        for (Legend t : list) {
            try {
                Date now = new Date();
                if (t.getOpentime() == null) {
                    t.setOpentime(now);

                }
                if (t.getCreatetime() == null) {
                    t.setCreatetime(now);

                }
                if (t.getUpdatetime() == null) {
                    t.setUpdatetime(now);

                }
                if (t.getTopbegintime() == null) {
                    t.setTopbegintime(now);

                }
                if (t.getTopendtime() == null) {
                    t.setTopendtime(now);

                }
                legendService.add(t);
            } catch (Exception ex) {
                logger.error(ex.getMessage());
                ex.printStackTrace();
            }
        }
        return redirect("/");
    }

    @RequestMapping(value = { "/list/{type}" }, method = RequestMethod.GET)
    public String list(Model model, HttpSession session,
            @PathVariable String type) {
        if (!isLogin(session) || type == null) {
            return redirect("/admin");
        }
        type = type.trim();
        if (type.equals("ad")) {
            Map<Integer, List<Ad>> ads = adService.getAllAds();
            model.addAttribute("ads", ads);
            model.addAttribute("tabletype", "ad");
        } else {
            List<Legend> nextServers = legendService.queryNextServers();
            List<Legend> priviousServers = legendService.queryBeforeServers();
            model.addAttribute("nextServers", nextServers);
            model.addAttribute("priviousServers", priviousServers);
            model.addAttribute("tabletype", "legend");
        }

        return "/admin/list";
    }

    @RequestMapping(value = { "/{type}/{id}" }, method = RequestMethod.GET)
    public String modify(Model model, HttpSession session,
            @PathVariable String type, @PathVariable String id) {
        if (!isLogin(session) || type == null) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException ex) {
            throw new ResourceNotFoundException(ex.getMessage());
        }

        type = type.trim();
        if (type.equals("ads")) {
            Ad ad = adService.find(idInt);
            if (ad == null) {
                throw new ResourceNotFoundException("找不到对应的资源");
            }
            model.addAttribute("ad", ad);
            model.addAttribute("tabletype", "ad");
            model.addAttribute("id", ad.getId());
        } else {
            Legend legend = legendService.find(idInt);
            if (legend == null) {
                throw new ResourceNotFoundException("找不到对应的资源");
            }
            model.addAttribute("legend", legend);
            model.addAttribute("tabletype", "legend");
            model.addAttribute("id", legend.getId());
        }
        addSelect(model);
        return "/admin/modify";
    }

    @RequestMapping(value = { "/{type}/{id}/delete" }, method = RequestMethod.GET)
    public String delete(Model model, HttpSession session,
            @PathVariable String type, @PathVariable String id) {
        if (!isLogin(session) || type == null) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException ex) {
            throw new ResourceNotFoundException(ex.getMessage());
        }

        type = type.trim();
        if (type.equals("ads")) {
            Ad ad = adService.find(idInt);
            if (ad != null) {
                adService.delete(ad);
            }
            type = "ad";

        } else {
            Legend legend = legendService.find(idInt);
            if (legend != null) {
                legendService.delete(legend);
            }
            type = "legend";
        }

        return redirect("/admin/list/" + type);
    }

    @RequestMapping(value = { "/{type}/add" }, method = RequestMethod.GET)
    public String add(Model model, HttpSession session,
            @PathVariable String type) {
        if (!isLogin(session) || type == null) {
            return redirect("/admin");
        }
        if (type.equals("ads")) {
            model.addAttribute("tabletype", "ad");
        } else {
            model.addAttribute("tabletype", "legend");
        }
        addSelect(model);
        return "/admin/add";
    }

    @RequestMapping(value = { "/legend/add" }, method = RequestMethod.PUT)
    public String addLegend(Model model, HttpSession session, Legend legend,
            String top_temp) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        Date now = new Date();
        legend.setUpdatetime(now);
        legend.setTop(Integer.parseInt(top_temp));
        legend.setCreatetime(now);
        legendService.add(legend);
        return redirect("/admin/list/legend");
    }

    @RequestMapping(value = { "/ad/add" }, method = RequestMethod.PUT)
    public String addAd(Model model, HttpSession session, Ad ad,
            String index_temp) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        Date now = new Date();
        ad.setUpdatetime(now);
        ad.setCreatetime(now);
        ad.setIndex(Integer.parseInt(index_temp));
        adService.add(ad);
        return redirect("/admin/list/ad");
    }

    @RequestMapping(value = { "/ad/{id}" }, method = RequestMethod.PUT)
    public String modify(Model model, HttpSession session,
            @PathVariable String id, Ad ad, String index_temp) {
        if (!isLogin(session) || id == null) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException ex) {
            throw new ResourceNotFoundException(ex.getMessage());
        }
        try {
            ad.setUpdatetime(new Date());
            ad.setIndex(Integer.parseInt(index_temp));
            adService.modify(ad);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex.getCause());
            throw new RuntimeException(ex.getMessage());
        }
        return redirect("/admin/ads/" + idInt);
    }

    @RequestMapping(value = { "/legend/{id}" }, method = RequestMethod.PUT)
    public String modify(Model model, HttpSession session,
            @PathVariable String id, Legend legend, String top_temp) {
        if (!isLogin(session) || id == null) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException ex) {
            throw new ResourceNotFoundException(ex.getMessage());
        }
        try {
            legend.setUpdatetime(new Date());
            legend.setTop(Integer.parseInt(top_temp));
            legendService.modify(legend);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex.getCause());
            throw new RuntimeException(ex.getMessage());
        }
        return redirect("/admin/servers/" + idInt);
    }

    // 日期转换器，这样就会作用到这个Controller里所有方法上
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(
                dateFormat, false));
    }

    private void addSelect(Model model) {
        List<Param> index = new ArrayList<Param>();
        Param param = new Param();
        param.setText(IndexState.top.getName());
        param.setValue(IndexState.top.getState() + "");
        index.add(param);
        param = new Param();
        param.setText(IndexState.left.getName());
        param.setValue(IndexState.left.getState() + "");
        index.add(param);
        param = new Param();
        param.setText(IndexState.right.getName());
        param.setValue(IndexState.right.getState() + "");
        index.add(param);
        param = new Param();
        param.setText(IndexState.bottom.getName());
        param.setValue(IndexState.bottom.getState() + "");
        index.add(param);
        model.addAttribute("index", index);
        List<Param> type = new ArrayList<Param>();
        param = new Param();
        param.setText(TypeState.recommend1.getName());
        param.setValue(TypeState.recommend1.getState() + "");
        type.add(param);
        param = new Param();
        param.setText(TypeState.recommend2.getName());
        param.setValue(TypeState.recommend2.getState() + "");
        type.add(param);
        model.addAttribute("type", type);
        List<Param> top = new ArrayList<Param>();
        param = new Param();
        param.setText(TopState.normal.getName());
        param.setValue(TopState.normal.getState() + "");
        top.add(param);
        param = new Param();
        param.setText(TopState.top1.getName());
        param.setValue(TopState.top1.getState() + "");
        top.add(param);
        model.addAttribute("top", top);
        List<Param> enable = new ArrayList<Param>();
        param = new Param();
        param.setText(EnableState.disable.getName());
        param.setValue(EnableState.disable.getState() + "");
        enable.add(param);
        param = new Param();
        param.setText(EnableState.enable.getName());
        param.setValue(EnableState.enable.getState() + "");
        enable.add(param);
        model.addAttribute("enable", enable);
    }

    @RequestMapping("/acticles")
    public String acticle(Model model, HttpSession session) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        List<Acticle> acticles = acticleService.findAll();
        model.addAttribute("acticles", acticles);
        return "/admin/acticles";
    }

    @RequestMapping(value = { "/acticles/{id}" }, method = RequestMethod.GET)
    public String acticle(Model model, HttpSession session,
            @PathVariable String id) throws Resource404Exception {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException e) {
            throw new Resource404Exception(e.getMessage());
        }
        Acticle acticle = acticleService.find(idInt);
        if (acticle == null) {
            throw new Resource404Exception("没有找到该资源");
        }
        model.addAttribute("acticle", acticle);
        return "/admin/modify_acticle";
    }

    @RequestMapping(value = { "/acticles/add" }, method = RequestMethod.GET)
    public String addActicle(Model model, HttpSession session) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        return "/admin/acticle";
    }

    @RequestMapping(value = { "/acticles/add" }, method = RequestMethod.PUT)
    public String addActicle(Model model, HttpSession session, Acticle acticle) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        Date date = new Date();
        acticle.setUpdatetime(date);
        acticle.setCreatetime(date);
        acticleService.add(acticle);
        return redirect("/admin/acticles/" + acticle.getId());
    }

    @RequestMapping(value = { "/acticles/{id}" }, method = RequestMethod.POST)
    public String updateActicle(Model model, HttpSession session,
            Acticle acticle) {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        Date date = new Date();
        acticle.setUpdatetime(date);
        acticle.setCreatetime(date);
        acticleService.add(acticle);
        return redirect("/admin/acticles/" + acticle.getId());
    }

    @RequestMapping(value = { "/acticles/{id}/delete" })
    public String deleteActicle(Model model, HttpSession session,
            @PathVariable String id) throws Resource404Exception {
        if (!isLogin(session)) {
            return redirect("/admin");
        }
        int idInt = 0;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException e) {
            throw new Resource404Exception(e.getMessage());
        }
        Acticle acticle = acticleService.find(idInt);
        if (acticle == null) {
            throw new Resource404Exception("没有找到该资源");
        }
        acticleService.delete(acticle);
        return redirect("/admin/acticles/");
    }
}
